﻿using CNKI.TPI.Web.Admin.Model;
using CNKI.TPI.Web.Search.Model;
using KNet.Data.Entity;
using KNet.Foundation.DRS;
using KNet.Foundation.DRS.Model;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;

namespace CNKI.TPI.Web.Base
{
    class FieldCompare : IEqualityComparer<SYS_CMS_DATABASE_FIELD>
    {
        public Boolean Equals(SYS_CMS_DATABASE_FIELD x, SYS_CMS_DATABASE_FIELD y)
        {
            return x.Field == y.Field; //return t1.Equals(t2);
        }

        public Int32 GetHashCode(SYS_CMS_DATABASE_FIELD obj)
        {
            return obj.ToString().ToUpper().GetHashCode();
        }
    }

    /// 预定义字段类型
    public enum ColumnType
    {
        FIELD_CHAR, FIELD_VCHAR, FIELD_MVCHAR,
        FIELD_INTEGER, FIELD_DATE, FIELD_TIME, FIELD_NUM,
        FIELD_STRING, FIELD_TEXT,
        FIELD_SOB, FIELD_LOB,
        /// FIELD_IMG,FIELD_URL,FIELD_REF,
        FIELD_AUTO,
        FIELD_STRCHAR, FIELD_TEXTCHAR, FIELD_LTEXT, FIELD_MTEXT, FIELD_MTEXTCHAR,
        /// 相应的支持Unicode的字段类型
        FIELD_NCHAR, FIELD_NVCHAR, FIELD_NMVCHAR,
        FIELD_NSTRING, FIELD_NSTRINGCHAR,
        FIELD_NMTEXT, FIELD_NTEXT, FIELD_NTEXTCHAR,
        /// Muti-StringChar
        FIELD_MSTRCHAR,
        FIELD_VSM,		/// 相似索引字段
        FIELD_NMSTRCHAR,
        FIELD_TNAME,	/// 表名字段，虚拟字段，只供读取，返回表名
        FIELD_TANAME,	/// 表显示名字段，虚拟字段，只供读取，返回表显示名称
        FIELD_MIXTEXT,		/// 混合文本字段，虚拟字段，只供检索，内容为空，实际内空由混合模型确定
        FIELD_MIXTEXTCHAR,	/// 混合文本字段，虚拟字段，只供检索，内容为空，实际内空由混合模型确定
        FIELD_MIXTEXTAUTO,	/// 混合文本字段，虚拟字段，只供检索，内容为空，实际内空由混合模型确定
        FIELD_FULLFIELD,	/// 全字段，虚拟字段，只供检索，内容为空，实际内空由混合模型确定
        FIELD_WORD,			/// 词条型字段
        FIELD_VWORD,
        FIELD_DOB,			/// 数字对象字段
        FIELD_RELEVANT,		/// 相关度字段，虚拟字段，只供读取，返回记录的相关度(动态值, 取值范围 0-100)
        FIELD_INT64,		/// 64位整数字段
        FIELD_SNAPSHOT,
        /// 相应的支持Unicode的字段类型
        FIELD_NLTEXT, FIELD_NMTEXTCHAR,
        FIELD_ECHAR,		/// 可枚举的CHAR
        FIELD_EMVCHAR,		/// 可枚举的MVCHAR
        FIELD_RECORDID,		/// 记录物理ID, 表ID+10位记录物理序号
        FIELD_SIMTEXT,		/// 似相文本字段
        FIELD_MIXSIMTEXT,	/// virtual col for FIELD_SIMTEXT type
        FIELD_PYTEXT,		/// 同音字段
        FIELD_PYTEXTCHAR,	/// 同音字段,不分词
        FIELD_NECHAR,
        FIELD_NEMVCHAR,
        FIELD_LMVCHAR,
        FIELD_NWORD,
        FIELD_NMQTEXT,
        FIELD_QDATE,
        /// 衍生列
        FIELD_DEDUCTION,
        FIELD_TITLE,
        FIELD_ABSTRACT,
        FIELD_COMPACTQTEXT,
        FILED_RANGEINTEGER,		/// FIELD_RANGEINTEGER
        FIELD_SEARCHENGINE,		/// 搜索引擎全字段
        FIELD_SEARCHENGINE_EX,	/// 搜索引擎全字段
        FIELD_NTITLE,
        FIELD_NABSTRACT,
        FIELD_NCOMPACTQTEXT,
        FIELD_EXTRACTORDATA,
        FIELD_TXTDATALINK,
        FIELD_NVWORD,
        FIELD_FINGERPRINT,
        FIELD_LARGEFINGERPRINT,
        FIELD_MQTEXT,
        FIELD_QTEXT,
        FIELD_MIDFINGERPRINT,
        FIELD_GENERALFP,
        FIELD_NQTEXT,

        FIELD_XML,
        FIELD_VIRTUAL,
        FIELD_DOCPATH,
        FIELD_DOCUMENT,
        FIELD_VECTOR,
        FIELD_NULL,
    };


    //public enum ColumnType
    //{
    //    //by dugg 2015.8.21  //修改数据库字段类型 
    //    FIELD_CHAR, FIELD_VCHAR, FIELD_MVCHAR, FIELD_INTEGER, FIELD_DATE, FIELD_TIME,
    //    FIELD_NUM, FIELD_STRING, FIELD_TEXT, FIELD_SOB, FIELD_LOB,
    //    /// FIELD_IMG,FIELD_URL,FIELD_REF,
    //    FIELD_AUTO, FIELD_STRCHAR, FIELD_TEXTCHAR, FIELD_LTEXT, FIELD_MTEXT, FIELD_MTEXTCHAR,
    //    /// 相应的支持Unicode的字段类型
    //    FIELD_NCHAR, FIELD_NVCHAR, FIELD_NMVCHAR, FIELD_NSTRING, FIELD_NSTRINGCHAR,
    //    FIELD_NMTEXT, FIELD_NTEXT, FIELD_NTEXTCHAR,
    //    /// Muti-StringChar
    //    FIELD_MSTRCHAR,
    //    FIELD_VSM,		/// 相似索引字段
    //    FIELD_VIRTUAL,	//FIELD_CLTD,		/// 动态聚类字段，虚拟字段，只供检索，内容为空，实际内空指向一个FIELD_VSM字段
    //    FIELD_TNAME,	/// 表名字段，虚拟字段，只供读取，返回表名
    //    FIELD_TANAME,	/// 表显示名字段，虚拟字段，只供读取，返回表显示名称

    //    FIELD_MIXTEXT,		/// 混合文本字段，虚拟字段，只供检索，内容为空，实际内空由混合模型确定
    //    FIELD_MIXTEXTCHAR,	/// 混合文本字段，虚拟字段，只供检索，内容为空，实际内空由混合模型确定
    //    FIELD_MIXTEXTAUTO,	/// 混合文本字段，虚拟字段，只供检索，内容为空，实际内空由混合模型确定

    //    FIELD_FULLFIELD,	/// 全字段，虚拟字段，只供检索，内容为空，实际内空由混合模型确定

    //    FIELD_DOCPATH,//FIELD_ORDERAUTHOR,	/// 作者排序虚拟字段
    //    FIELD_DOCUMENT,//FIELD_ORDERSTRING,	/// 串排序虚拟字段

    //    FIELD_DOB,			/// 数字对象字段

    //    FIELD_RELEVANT,		/// 相关度字段，虚拟字段，只供读取，返回记录的相关度(动态值, 取值范围 0-100)

    //    FIELD_INT64,		/// 64位整数字段
    //    FIELD_SNAPSHOT,
    //    /// 相应的支持Unicode的字段类型
    //    FIELD_VECTOR,/*FIELD_NLTEXT*/
    //    FIELD_XML,/*FIELD_NMTEXTCHAR*/
    //    FIELD_ECHAR,		/// 可枚举的CHAR
    //    FIELD_EMVCHAR,		/// 可枚举的MVCHAR

    //    FIELD_RECORDID,		/// 记录物理ID, 表ID+10位记录物理序号

    //    FIELD_SIMTEXT,		/// 似相文本字段
    //    FIELD_MIXSIMTEXT,	/// virtual col for FIELD_SIMTEXT type
    //    FIELD_PYTEXT,		/// 同音字段
    //    FIELD_PYTEXTCHAR,	/// 同音字段,不分词
    //    //FIELD_PTEXT,FIELD_ADVTEXT,	
    //    FIELD_LMVCHAR,
    //    FIELD_QDATE,
    //    FIELD_NULL,
    //    //FIELD_HTEXT,
    //    //FIELD_QUICKTEXT,
    //    //FIELD_QUERY,// 查询时产生的虚拟列，如分组时的count(*)列

    //};

    public class DRSManager
    {
        private IDataContext context = null;

        public DRSManager()
        {
            context = new DataContext();
        }

        public static string GetSingleDrsName(int dbID)
        {
            return "drs_single_" + dbID;
        }

        public static string GetSingleDbSourceName(int dbID)
        {
            return "dbsource_single_" + dbID;
        }

        public static string GetMultiDrsName()
        {
            return "drs_multi";
        }

        public static string GetMultiDbSourceName(int dbID)
        {
            return "dbsource_multi_" + dbID;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool UpdateDRSInfo()
        {
            bool result = false;
            try
            {
                IList<SYS_CMS_DATABASE> databaseList = GetDatabase();
                if (databaseList != null)
                {
                    foreach (SYS_CMS_DATABASE item in databaseList)
                    {
                        UpdateSingleDRSInfo(item);
                    }
                }
                result = true;
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool UpdateMultiDRSInfo()
        {
            bool result = false;
            try
            {
                //更新Retrieval
                IList<SYS_CMS_US_FIELD> usFieldList = GetUSField();
                IList<SYS_CMS_DATABASE_FIELD> dbFieldList = ConvertUSField(usFieldList);
                string drsName = GetMultiDrsName();
                if (dbFieldList != null && dbFieldList.Count > 0)
                {
                    CreateRetrieval(drsName, dbFieldList);
                }
                //更新DbResource
                IList<SYS_CMS_US_FIELDMAP> fieldMap = GetUSFieldMap();
                IEnumerable<int> dbList = fieldMap.Select(c => c.DBID).ToList<int>().Distinct();
                IList<SYS_CMS_DATABASE_FIELD> mapFieldList = null;
                SYS_CMS_DATABASE_FIELD mapField = null;
                foreach (int dbID in dbList)
                {
                    SYS_CMS_DATABASE dbInfo = GetDatabase(dbID);
                    if (null == dbInfo)
                    {
                        continue;
                    }
                    dbFieldList = GetDBField(dbInfo.DatabaseCode);
                    IList<SYS_CMS_US_FIELDMAP> fieldInfos = fieldMap.Where(c => c.DBID == dbID).ToList();
                    mapFieldList = new List<SYS_CMS_DATABASE_FIELD>();
                    foreach (SYS_CMS_US_FIELDMAP field in fieldInfos)
                    {
                        mapField = new SYS_CMS_DATABASE_FIELD();
                        mapField.Field = "";
                        mapField.StrDataType = "";
                        IList<SYS_CMS_US_FIELD> usField = usFieldList.Where(c => c.SYSID == field.USFieldID).ToList();
                        if (usField != null && usField.Count > 0)
                        {
                            mapField.Field = usField[0].Name;
                            mapField.StrDataType = usField[0].DataType;
                        }

                        mapField.DataType = 0;
                        mapField.Mapping = "";
                        IList<SYS_CMS_DATABASE_FIELD> dbField = dbFieldList.Where(c => c.SysID == field.FieldID).ToList();
                        if (dbField != null && dbField.Count > 0)
                        {
                            mapField.DataType = dbField[0].DataType;
                            mapField.Mapping = dbField[0].Field;
                        }

                        mapFieldList.Add(mapField);
                    }
                    CreateDbResource(drsName, GetMultiDbSourceName(dbInfo.SysID), dbInfo, mapFieldList);
                }
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private IList<SYS_CMS_US_FIELD> GetUSField()
        {
            IList<SYS_CMS_US_FIELD> result = new List<SYS_CMS_US_FIELD>();
            try
            {
                IList<SYS_CMS_US_FIELD> fieldList = context.GetAll<SYS_CMS_US_FIELD>();
                if (fieldList != null && fieldList.Count > 0)
                {
                    result = fieldList;
                }
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private IList<SYS_CMS_DATABASE_FIELD> ConvertUSField(IList<SYS_CMS_US_FIELD> fieldList)
        {
            IList<SYS_CMS_DATABASE_FIELD> result = new List<SYS_CMS_DATABASE_FIELD>();
            try
            {
                if (fieldList != null && fieldList.Count > 0)
                {
                    SYS_CMS_DATABASE_FIELD fieldInfo = null;
                    foreach (SYS_CMS_US_FIELD item in fieldList)
                    {
                        fieldInfo = new SYS_CMS_DATABASE_FIELD();
                        fieldInfo.Field = item.Name;
                        fieldInfo.StrDataType = item.DataType;
                        result.Add(fieldInfo);
                    }
                }
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private IList<SYS_CMS_US_FIELDMAP> GetUSFieldMap()
        {
            IList<SYS_CMS_US_FIELDMAP> result = new List<SYS_CMS_US_FIELDMAP>();
            try
            {
                IList<SYS_CMS_US_FIELDMAP> fieldMapList = context.GetAll<SYS_CMS_US_FIELDMAP>();
                if (fieldMapList != null && fieldMapList.Count > 0)
                {
                    result = fieldMapList;
                }
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbID"></param>
        /// <returns></returns>
        public bool UpdateSingleDRSInfo(int dbID)
        {
            bool result = false;
            try
            {
                SYS_CMS_DATABASE dbInfo = GetDatabase(dbID);
                if (dbInfo != null)
                {
                    result = UpdateSingleDRSInfo(dbInfo);
                }
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbID"></param>
        /// <returns></returns>
        public bool UpdateSingleDRSInfo(SYS_CMS_DATABASE dbInfo)
        {
            bool result = false;
            try
            {
                string drsName = GetSingleDrsName(dbInfo.SysID);
                if (dbInfo != null)
                {
                    IList<SYS_CMS_DATABASE_FIELD> pubulishFieldList = GetDBField(dbInfo.DatabaseCode);
                    if (pubulishFieldList != null && pubulishFieldList.Count > 0)
                    {
                        CreateRetrieval(drsName, pubulishFieldList);
                        CreateDbResource(drsName, GetSingleDbSourceName(dbInfo.SysID), dbInfo, pubulishFieldList);
                    }
                }
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbID"></param>
        /// <returns></returns>
        private IList<SYS_CMS_DATABASE_FIELD> GetDBField(string dbCode)
        {
            IList<SYS_CMS_DATABASE_FIELD> result = null;
            try
            {
                ExpressionCombine<SYS_CMS_DATABASE_FIELD> exp = new ExpressionCombine<SYS_CMS_DATABASE_FIELD>();
                exp.And("DATABASECODE", OperatorType.Equal, dbCode);
                result = context.Get<SYS_CMS_DATABASE_FIELD>(exp.Compile());
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbID"></param>
        /// <returns></returns>
        private SYS_CMS_DATABASE GetDatabase(int dbID)
        {
            SYS_CMS_DATABASE result = null;
            try
            {
                ExpressionCombine<SYS_CMS_DATABASE> exp = new ExpressionCombine<SYS_CMS_DATABASE>();
                exp.And("SYSID", OperatorType.Equal, dbID);
                IList<SYS_CMS_DATABASE> dbList = context.Get<SYS_CMS_DATABASE>(exp.Compile());
                if (dbList != null && dbList.Count > 0)
                {
                    result = dbList[0];
                }
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbID"></param>
        /// <returns></returns>
        private IList<SYS_CMS_DATABASE> GetDatabase()
        {
            IList<SYS_CMS_DATABASE> result = null;
            try
            {
                ExpressionCombine<SYS_CMS_DATABASE> exp = new ExpressionCombine<SYS_CMS_DATABASE>();
                //exp.And("DATABASEPUBFLAG", OperatorType.Equal, 1);
                //exp.And("VISIBLEFLAG", OperatorType.Equal, 1);
                exp.And("SearchType", OperatorType.GreaterThan, 0);
                result = context.Get<SYS_CMS_DATABASE>(exp.Compile());
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="drsName"></param>
        /// <param name="columnList"></param>
        private void CreateRetrieval(string drsName, IList<SYS_CMS_DATABASE_FIELD> columnList)
        {
            Retrieval retrieval = new Retrieval();
            retrieval.CacheTime = 30000;
            retrieval.Timeout = 30000;
            retrieval.Name = drsName;
            retrieval.Columns = new List<RetrievalColumn>();

            //添加字段信息
            RetrievalColumn column = new RetrievalColumn();
            foreach (SYS_CMS_DATABASE_FIELD item in columnList)
            {
                column = new RetrievalColumn();
                column.Name = item.Field;
                if (string.IsNullOrEmpty(item.StrDataType))
                {
                    column.Type = GetColumnType((ColumnType)item.DataType);
                }
                else
                {
                    column.Type = item.StrDataType;
                }

                retrieval.Columns.Add(column);
            }
            context.RemoveRetrieval(drsName);
            OperateResult operateResult = context.AppendRetrieval(retrieval);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="drsName"></param>
        /// <param name="dbInfo"></param>
        /// <param name="columnList"></param>
        private void CreateDbResource(string drsName, string dbResourceName, SYS_CMS_DATABASE dbInfo, IList<SYS_CMS_DATABASE_FIELD> columnList)
        {
            IDictionary<string, string> connectionInfo = GetDBConnectionInfo();
            DbResource dbResource = new DbResource();
            dbResource.Type = "ccnd";
            dbResource.Name = dbResourceName;
            dbResource.DefaultOrder = "Relevant";
            switch ((SearchType)dbInfo.SearchType)
            {
                case SearchType.TPI:
                    dbResource.TableName = dbInfo.DatabaseCode + "_METADATA";
                    dbResource.ObjectName = dbInfo.DatabaseCode + "_METADATA";
                    dbResource.Uri = connectionInfo["serverIp"];
                    dbResource.Port = connectionInfo["port"];
                    dbResource.UserId = connectionInfo["username"];
                    dbResource.Password = connectionInfo["password"];
                    dbResource.ResourceType = "kbase";
                    break;
                case SearchType.CNKI:
                case SearchType.KSPIRDER:
                    dbResource.TableName = dbInfo.VViewName;
                    dbResource.ObjectName = dbInfo.VViewName;
                    dbResource.Uri = dbInfo.VIP;
                    dbResource.Port = dbInfo.VPort.ToString();
                    dbResource.UserId = dbInfo.VUserName;
                    dbResource.Password = dbInfo.VPassWord;
                    dbResource.ResourceType = "kbase";
                    break;
                default:
                    dbResource.TableName = dbInfo.VViewName;
                    dbResource.ObjectName = dbInfo.VViewName;
                    dbResource.Uri = dbInfo.VIP;
                    dbResource.Port = dbInfo.VPort.ToString();
                    dbResource.UserId = dbInfo.VUserName;
                    dbResource.Password = dbInfo.VPassWord;
                    string resourceType = "kbase";
                    IDictionary<string, int> list = ConfigHelper.GetExtDataSourceList();
                    foreach (string key in list.Keys)
                    {
                        if (list[key] == dbInfo.SearchType)
                        {
                            resourceType = key;
                            break;
                        }
                    }
                    dbResource.ResourceType = resourceType;
                    break;
            }

            dbResource.Link = "http://test.com";
            dbResource.Title = dbInfo.SysID + "#" + dbInfo.DatabaseCode + "#" + dbInfo.DatabaseName + "#" + GetDBType(dbInfo.DatabaseType);
            
            dbResource.Mappings = new List<DbResourceMapping>();
            dbResource.Extended = 1 == dbInfo.IsUnicode ? "IsUnicode=true;" : "";

            //添加字段信息
            DbResourceMapping dbResourceMapping = null;
            foreach (SYS_CMS_DATABASE_FIELD item in columnList)
            {
                dbResourceMapping = new DbResourceMapping();
                dbResourceMapping.Name = item.Field;
                if (string.IsNullOrEmpty(item.Mapping))
                {
                    dbResourceMapping.Mapping = item.Field;
                }
                else
                {
                    dbResourceMapping.Mapping = item.Mapping;
                }
                if (string.IsNullOrEmpty(item.StrDataType))
                {
                    dbResourceMapping.Type = GetColumnType((ColumnType)item.DataType);
                }
                else
                {
                    dbResourceMapping.Type = item.StrDataType;
                }
                if (((ColumnType)item.DataType).ToString().Length > 6)
                {
                    dbResourceMapping.DbType = ((ColumnType)item.DataType).ToString().Substring(6);
                }
                else
                {
                    dbResourceMapping.DbType = ((ColumnType)item.DataType).ToString();
                }
                dbResource.Mappings.Add(dbResourceMapping);
            }
            OperateResult operateResult = context.RemoveResource(drsName, dbResource.Name);
            operateResult = context.AppendDbResource(drsName, dbResource, 1, dbResource.Name);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbType"></param>
        /// <returns></returns>
        private string GetColumnType(ColumnType dbType)
        {
            string result = "System.String";
            try
            {
                switch (dbType)
                {
                    case ColumnType.FIELD_INTEGER:
                        result = "System.Int32";
                        break;
                    case ColumnType.FIELD_DATE:
                        result = "System.DateTime";
                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbType"></param>
        /// <returns></returns>
        public static string GetDBType(int dbType)
        {
            string result = "0";
            try
            {
                switch (dbType)
                {
                    case 1:
                    case 4:
                    case 5:
                    case 6:
                        result = dbType.ToString();
                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private IDictionary<string, string> GetDBConnectionInfo()
        {
            IDictionary<string, string> result = new Dictionary<string, string>();
            string connectionString = ConfigHelper.GetConnSettingsValue("SysDB");
            string[] dbInfo = connectionString.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            string key, value;
            string[] param;
            foreach (string item in dbInfo)
            {
                param = item.Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                key = param[0].Contains(":") ? param[0].Substring(param[0].IndexOf(':') + 1) : param[0];
                if (param.Length > 1)
                {
                    value = param[1];
                }
                else
                {
                    value = "";
                }
                result.Add(key, value);
            }
            return result;
        }
    }
}
